using AutoMapper;
using MediatR;
using Microsoft.EntityFrameworkCore;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Work.API.Applications.Read.Commands;
using Work.API.Dtos;
using Work.ErrorCode;
using Work.Infrastructure.Interfaces;

namespace Work.API.Applications.Read.CommandHandlers
{
    /// <summary>
    /// 核算总金额处理器
    /// </summary>
    public class CalculateTotalAmountQueryHandler : IRequestHandler<CalculateTotalAmountQuery, ApiResult<SettlementSummaryDto>>
    {
        private readonly IBaseRepository<Domain.Appintment> _appointmentRepo;
        private readonly IBaseRepository<Domain.PrescriptionItem> _prescriptionItemRepo;
        private readonly IMapper _mapper;

        public CalculateTotalAmountQueryHandler(
            IBaseRepository<Domain.Appintment> appointmentRepo,
            IBaseRepository<Domain.PrescriptionItem> prescriptionItemRepo,
            IMapper mapper)
        {
            _appointmentRepo = appointmentRepo;
            _prescriptionItemRepo = prescriptionItemRepo;
            _mapper = mapper;
        }

        public async Task<ApiResult<SettlementSummaryDto>> Handle(CalculateTotalAmountQuery request, CancellationToken cancellationToken)
        {
            var result = new ApiResult<SettlementSummaryDto>();

            try
            {
                // 1. 获取预约信息（包含挂号费、其他费）
                var appointment = await _appointmentRepo.GetById(request.AppointmentId);
                if (appointment == null)
                {
                    result.Code = ApiEnum.失败;
                    result.Message = "预约不存在";
                    result.Data = null!;
                    return result;
                }

                // 2. 获取未支付的药品明细
                var prescriptionItems = await _prescriptionItemRepo.GetAll()
                    .Where(x => x.AppointmentId == request.AppointmentId 
                             && x.PaymentStatus == "未支付")
                    .ToListAsync(cancellationToken);

                // 3. 计算总金额
                var registrationFee = appointment.RegistrationFee ?? 0;
                var otherFee = appointment.OtherFee ?? 0;
                var medicineTotal = prescriptionItems.Sum(x => x.TotalAmount);
                var totalAmount = registrationFee + otherFee + medicineTotal;

                // 4. 构建结算汇总DTO
                var summary = new SettlementSummaryDto
                {
                    RegistrationFee = registrationFee,
                    OtherFee = otherFee,
                    MedicineTotalAmount = medicineTotal,
                    TotalAmount = totalAmount,
                    PrescriptionItems = _mapper.Map<List<PrescriptionItemDto>>(prescriptionItems)
                };

                result.Code = ApiEnum.成功;
                result.Message = "核算成功";
                result.Data = summary;
            }
            catch (System.Exception ex)
            {
                result.Code = ApiEnum.失败;
                result.Message = $"核算失败：{ex.Message}";
                result.Data = null!;
            }

            return result;
        }
    }
}

